import 'dart:convert';

import 'package:city_pickers/city_pickers.dart';
import 'package:flutter/material.dart';
import 'package:hkzf_flutter/config.dart';
import 'package:hkzf_flutter/dio/general_type.dart';
import 'package:hkzf_flutter/scoped_model/city_model.dart';
import 'package:hkzf_flutter/utils/common_toast.dart';
import 'package:hkzf_flutter/utils/scoped_model_helper.dart';
import 'package:hkzf_flutter/utils/store.dart';
import 'package:hkzf_flutter/widgets/common_image.dart';


class SearchBarWidget extends StatefulWidget {
  final bool? showLocation;// 是否展示位置按钮
  final Function? goBackCallback;// 回退按钮函数
  final String? inputValue ;// 搜索框输入值
  final String? defaultInputValue ;// 默认搜索框输入值
  final Function? onCancel;// 取消按钮函数
  final bool? showMap;// 是否展示地图按钮
  final Function? onSearch;// 用户点击搜索框触发函数
  final ValueChanged<String>? onSearchSubmit;// 用户点击搜索按钮触发函数
  
  const SearchBarWidget({
    super.key, 
    this.showLocation, 
    this.goBackCallback, 
    this.inputValue = '', 
    this.defaultInputValue = '请输入搜索词', 
    this.onCancel,
    this.showMap, 
    this.onSearch, 
    this.onSearchSubmit
  });

  @override
  State<SearchBarWidget> createState() => _SearchBarWidgetState();
}
// expression ?? defaultValue, ?? 是 空值合并运算符
// 如果 expression 不为 null，则返回 expression 的值；
// 如果 expression 为 null，则返回 defaultValue。
class _SearchBarWidgetState extends State<SearchBarWidget> {
  String _searchWord = '';// 输入内容
  // late： 延迟初始化变量，在第一次调用时才初始化变量的值。
  late TextEditingController _controller;
  late FocusNode _focusNode;// 焦点控制

  // initState： 初始化在 widget 构建之前需要准备的资源，例如控制器 (TextEditingController)、动画控制器、订阅流等类似前端初始化声明周期函数
  // 调用时机：在 widget 被插入到 widget 树中时调用，只调用一次。
  @override
  void initState() {// 初始化状态
    _controller = TextEditingController(text: widget.inputValue);
    _focusNode = FocusNode();
    super.initState();
    
  }
  // dispose：用于释放不再需要的资源，避免内存泄漏，例如控制器 (TextEditingController)、动画控制器、订阅流等类似前端的销毁生命周期函数
  // 当 widget 从 widget 树中移除时调用，通常在页面关闭或 widget 被销毁时触发。
  @override
  void dispose() {
    // 在 dispose 方法中释放控制器资源，避免内存泄漏
    _controller.dispose();
    super.dispose();
  }

  // 更新输入框内容
  _onChanged(String value){ 
    setState(() {
      _searchWord = value;
    });
  }
  // 清空输入框内容
  _onClean(){
    _controller.clear();
    setState(() {
      _searchWord = '';
    });
  }
  // 获取城市信息
  _getCity() async{
    // 从本地存储中获取城市信息
    var store = await Store.getInstance();
    var cityString =await store.getString(StoreKeys.city);
    if(cityString == null) return;
    // json.decode反序列化将JSON字符串转换为一个 Map 对象
    var city = GeneralType.fromJson(json.decode(cityString));
    // 再次设置城市信息到状态管理中
    ScopedModelHelper.getModel<CityModel>(context).city = city;
  }
  // 保存城市信息
  _saveCity(GeneralType city) async{ 
    // 保存城市信息到状态管理中
    ScopedModelHelper.getModel<CityModel>(context).city = city;
    // 将城市信息保存到本地存储中
    Store store = await Store.getInstance();
    // city.toJson其转换为一个 Map（键值对）
    // json.encode函数只能序列化某些特定类型的对象（如 Map、List、基本类型如 String、int、double、bool 等）转化成JSON 字符串
    var cityString = json.encode(city.toJson());
    store.setString(StoreKeys.city, cityString);


  }
  // 改变定位城市
  _changeLocation() async{
    var result =await CityPickers.showCitiesSelector(
      context: context,
      theme: ThemeData(primaryColor: Colors.green)
    );
    String? cityName = result?.cityName;
    if(cityName == null) return;
    print('选择的城市: $cityName');
    var city = Config.availableCitys.firstWhere((city) => cityName.startsWith(city.name as Pattern),orElse:(){
       CommonToast.showToast('$cityName该城市暂未开通租房服务');
       return GeneralType(null, null);
      }
    ); 
    if(city.name == null) return;
    _saveCity(city);
  }

  @override
  Widget build(BuildContext context) {
    // 组件刷新重新获取状态管理中的选择城市信息
    var city = ScopedModelHelper.getModel<CityModel>(context).city;
    if(city == null){
      city = Config.availableCitys.first;
      _getCity();
    }

    return Container(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if(widget.showLocation ?? false )Padding(
            padding: EdgeInsets.only(right: 10.0),
            child: GestureDetector(
              onTap: ()=>_changeLocation(),
              child: Row(
              children: [
                const Icon(Icons.room,color: Colors.green,size: 20.0,),
                Text(
                  city.name ?? '暂无',
                  style: const TextStyle(fontSize: 16.0,color: Colors.black,fontWeight: FontWeight.bold),)
              ],
             ),
            ),
          ),
          if(widget.goBackCallback != null)Padding(
            padding: EdgeInsets.only(right: 10.0),
            child: InkWell(
              onTap: ()=> widget.goBackCallback!(),
              child: const Icon(Icons.chevron_left,color: Colors.black87,size: 25.0,),
            ),
          ),
          Expanded(
            child: Container(
              height: 34.0,
              decoration: BoxDecoration(
                color: Colors.grey[200],
                borderRadius: BorderRadius.circular(17)
              ),
              child: TextField(
                controller: _controller,// 绑定TextField控件
                focusNode: _focusNode,// 绑定FocusNode控件
                onTap:(){
                  if(widget.onSearch != null){
                    widget.onSearch!();//当用户点击输入框时，触发 widget.onSearch 回调函数。
                  }
                  if(widget.onSearchSubmit == null){// 如果不是搜索页则控制失去焦点,// 即是没有提交的回调函数表示不是搜索页面
                    _focusNode.unfocus();
                  }
                },
                onSubmitted: widget.onSearchSubmit,//用户点击键盘“搜索”按钮时会触发 widget.onSearchSubmit 回调
                textInputAction: TextInputAction.search,//设置软键盘右下角的动作为“搜索”，通常显示为 “Search” 图标或文字
                onChanged: (String value){// 输入内容改变时触发
                  _onChanged(value);
                },
                decoration: InputDecoration(
                  hintText: '请输入搜索词',
                  hintStyle: const TextStyle(fontSize: 16.0,color: Colors.grey),
                  contentPadding: const EdgeInsets.only(left: -10.0,top:-2.0),
                  border: InputBorder.none,
                  icon: const Padding(
                    padding: EdgeInsets.only(left: 10.0),
                    child: Icon(Icons.search,size: 20.0,color: Colors.grey,),
                  ),// 自定义图标位置
                  suffixIcon: IconButton(
                    icon: Icon(
                      Icons.clear, 
                      size: 20.0, 
                      color:_searchWord == '' ? Colors.grey[200]:Colors.grey,
                    ),// 后置图标
                    onPressed: ()=>{
                      _onClean()
                    },
                  ),
                ),
              ),
            )
          ),
          if(widget.onCancel != null)GestureDetector(
            onTap: ()=> widget.onCancel!(),
            child: const Padding(
              padding: EdgeInsets.only(left: 10.0),
              child:  Text('取消',style: TextStyle(
              fontSize: 16.0,
              color: Colors.black,
              fontWeight: FontWeight.bold
            ),),
            )
          ),
          if(widget.showMap ?? false)Container(
            margin: const EdgeInsets.only(left: 10.0),
            child: InkWell(
              onTap: ()=> {},
              child: const CommonImage(src: 'static/icons/widget_search_bar_map.png')
            ),
          )
        ],
      ),
    );
  }
}